/*
 * Lenovo Group
 * Copyright (c) 2015-2016 All Rights Reserved.
 * 
 * Project Name:assign-tracer
 * Create Time: 2016年1月27日 上午11:31:03
 */
package com.lenovo.lmrp.server.assigntracer.events;

import java.util.Objects;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.inject.Inject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.lenovo.lmrp.api.constant.SendType;
import com.lenovo.lmrp.api.model.entity.EngineerTerminalPO;
import com.lenovo.lmrp.api.model.view.GrabRecode;
import com.lenovo.lmrp.api.model.view.LoginData;
import com.lenovo.lmrp.base.mq.MQAppGatewayEvent;
import com.lenovo.lmrp.base.mq.MQContent;
import com.lenovo.lmrp.server.assigntracer.domain.engineer.EngineerBO;
import com.lenovo.lmrp.server.assigntracer.domain.engineer.IEngineerRepository;
import com.lenovo.lmrp.server.assigntracer.util.cache.AssignTracerCache;
import com.lenovo.lmrp.server.assigntracer.util.grap.GrabFactory;
import com.lenovo.lmrp.server.assigntracer.util.grap.IGrab;
import com.lenovo.sdc.framework.cache.ACacheClient;
import com.lenovo.sdc.framework.cache.CacheItem;
import com.lenovo.sdc.framework.mq.IMQReceiver;
import com.lenovo.sdc.framework.util.JSONHelper;
import com.lenovo.sdc.framework.util.exception.ErrorCode;
import com.lenovo.sdc.framework.util.exception.TraceableException;

/**
 * @author songyz
 *
 */
public class AppGatewayHandle implements IMQReceiver {

	private final static Logger logger = LoggerFactory.getLogger(AppGatewayHandle.class);
	private Lock lock = new ReentrantLock();// 锁

	private IEngineerRepository engineerRepository;

	@Inject
	public void set(IEngineerRepository engineerRepository) {
		this.engineerRepository = engineerRepository;
	}

	@Override
	public void onMessage(String topic, Object content) {
		if (logger.isDebugEnabled())
			logger.debug("Message received:========>>topic:{} content:{}", topic, content);
		MQContent mqContent = null;
		try {
			mqContent = JSONHelper.fromJSON((String) content, MQContent.class);
		} catch (Exception e) {
			throw new TraceableException(ErrorCode.COMM_PARSE_FAILED, e);
		}

		switch (MQAppGatewayEvent.getMQAppGatewayEvent(mqContent.getEvent())) {
		case LOGIN:// 登录
			EngineerTerminalPO engineerTerminalPO = transformEngineerTerminalPO(mqContent);
			EngineerBO engineerBO = engineerRepository.createEngineerWithTerminal(mqContent.getItsmcode(),
					engineerTerminalPO.getEngineerid());
			boolean isNew = engineerBO.traceLogin(engineerTerminalPO);
			if (isNew)
				engineerRepository.store(mqContent.getItsmcode(), engineerTerminalPO);
			else
				engineerRepository.update(mqContent.getItsmcode(), engineerTerminalPO);
			break;
		case LOGOUT:// 登出
			engineerTerminalPO = transformEngineerTerminalPO(mqContent);
			engineerBO = engineerRepository.createEngineerWithTerminal(mqContent.getItsmcode(),
					engineerTerminalPO.getEngineerid());
			engineerBO.traceLoginOut(engineerTerminalPO);
			break;
		case FORCELOGOUT:// 强制登出
			engineerTerminalPO = transformEngineerTerminalPO(mqContent);
			engineerBO = engineerRepository.createEngineerWithTerminal(mqContent.getItsmcode(),
					engineerTerminalPO.getEngineerid());
			engineerBO.forceLogOut(mqContent);
			break;
		case GRAB:// 抢单
			GrabRecode grabRecode = null;
			lock.lock();
			try {
				try {
					grabRecode = JSONHelper.fromJSON(JSONHelper.toJSON(mqContent.getContent()), GrabRecode.class);
				} catch (Exception e) {
					throw new TraceableException(ErrorCode.COMM_PARSE_FAILED, e);
				}
				if (Objects.isNull(grabRecode.getTicketId()) || Objects.isNull(grabRecode.getEngineerId()))
					return;

				grabRecode.setItsmCode(mqContent.getItsmcode());
				ACacheClient client = AssignTracerCache.getClient();
				CacheItem<IGrab> cacheItem = client.get(mqContent.getItsmcode(), grabRecode.getTicketId());
				IGrab grabBuff = cacheItem.getValue();
				if (Objects.nonNull(grabBuff)) {
					grabBuff.put(grabRecode);
					client.replace(new CacheItem<IGrab>(grabRecode.getTicketId(), grabBuff, mqContent.getItsmcode(),
							GrabFactory.GRAB_CACHE_TIME));
				} else {
					// 如果抢单策略为空，有可能是因为服务重启，缓存清空,现在将抢单策略的容器进行初始化
					IGrab iGrab = GrabFactory.getIGrab();
					iGrab.put(grabRecode);
					client.put(new CacheItem<IGrab>(grabRecode.getTicketId(), iGrab, mqContent.getItsmcode(),
							GrabFactory.GRAB_CACHE_TIME));
				}
			} catch (Exception e) {
				logger.warn("grab ticket error itsmCode:[{}] ticketId:[{}],engineerId:[{}]", mqContent.getItsmcode(),
						grabRecode.getTicketId(), grabRecode.getEngineerId());
			} finally {
				lock.unlock();
			}
			break;
		default:
			logger.warn("ignore event code {}", mqContent.getEvent());
		}
	}

	// 数据转换--登录登出
	public static EngineerTerminalPO transformEngineerTerminalPO(MQContent mqContent) {
		LoginData content = null;
		try {
			content = JSONHelper.fromJSON(JSONHelper.toJSON(mqContent.getContent()), LoginData.class);
		} catch (Exception e) {
			throw new TraceableException(ErrorCode.COMM_PARSE_FAILED, e);
		}
		EngineerTerminalPO engineerTerminalPO = new EngineerTerminalPO();
		engineerTerminalPO.setCid(content.getCid());
		engineerTerminalPO.setCidtype(SendType.GETUI.getSendType());

		engineerTerminalPO.setEngineerid(content.getLoginname());
		engineerTerminalPO.setTerminalid(content.getDeviceid());
		return engineerTerminalPO;
	}
}
